﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Collections.ObjectModel;
using System.Collections;
using Barbar.Colonization.Core;
using System.Xml.Serialization;

namespace Barbar.Colonization.Model.RuleSets {
  public class XmlImageStack : Collection<XmlImageRef>, IImageStack, IRulesetDeserialization {
    private Collection<IImage> m_Images;
    private Bitmap m_MergedImage;

    private void EnsureMergedImage() {
      if (m_MergedImage != null)
        return;
      if (m_Images == null || m_Images.Count == 0)
        throw new ColonizationException(ExceptionTranslator.ImageStackIsEmpty);
      Size defaultSize = m_Images[0].Image.Size;
      foreach (IImage image in m_Images) {
        if (image.Image.Size != defaultSize)
          throw new ColonizationException(ExceptionTranslator.ImagesInStackHasDifferentSize);
      }
      Bitmap mergeBitmap = new Bitmap(defaultSize.Width, defaultSize.Height);
      using (Graphics graphics = Graphics.FromImage(mergeBitmap)) {
        foreach (IImage image in m_Images) {
          graphics.DrawImage(image.Image, 0, 0, defaultSize.Width, defaultSize.Height);
        }
      }
      m_MergedImage = mergeBitmap;
    }

    #region IImageStack Members

    Bitmap IImageStack.MergedImage {
      get {
        EnsureMergedImage();
        return m_MergedImage;
      }
    }

    IEnumerable<IImage> IImageStack.Images {
      get { return (IEnumerable<IImage>)m_Images.GetEnumerator(); }
    }

    #endregion

    #region IRulesetDeserialization Members

    void IRulesetDeserialization.OnDeserialization(XmlRuleSet ruleSet) {
      m_Images = new Collection<IImage>();
      foreach (XmlImageRef imageRef in this) {
        XmlImage result = null;
        foreach (XmlImage image in ruleSet.Images)
          if (image.Id == imageRef.IdRef) {
            result = image;
            break;
          }
        if (result == null)
          throw new ColonizationException(ExceptionTranslator.ReferencedImageNotFound);
        m_Images.Add(result);
      }
    }

    #endregion
  }
}
